<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><title>Github Actions 为什么这么香 | CC的部落格</title><meta name="author" content="CC康纳百川"><meta name="copyright" content="CC康纳百川"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="ffffff"><article data-clarity-region="article"></article><meta name="description" content="本篇文章简单介绍了 Github Actions 的用法，以及一些变量的解释"><meta property="og:type" content="article"><meta property="og:title" content="Github Actions 为什么这么香"><meta property="og:url" content="https://blog.ccknbc.cc/posts/why-github-actions-is-so-popular/"><meta property="og:site_name" content="CC的部落格"><meta property="og:description" content="本篇文章简单介绍了 Github Actions 的用法，以及一些变量的解释"><meta property="og:locale" content="zh_CN"><meta property="og:image" content="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/731ab9880a63b4eb0d82d354cdbdadec_w2240_h1260_s743.jpg"><meta property="article:published_time" content="2020-10-06T02:51:58.000Z"><meta property="article:modified_time" content="2020-10-06T04:00:00.000Z"><meta property="article:author" content="CC康纳百川"><meta property="article:tag" content="工具"><meta name="twitter:card" content="summary"><meta name="twitter:image" content="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/731ab9880a63b4eb0d82d354cdbdadec_w2240_h1260_s743.jpg"><link rel="shortcut icon" href="/favicon.ico"><link rel="canonical" href="https://blog.ccknbc.cc/posts/why-github-actions-is-so-popular/"><link rel="preconnect" href="https://jsd.cdn.zzko.cn"><link rel="preconnect" href="//static.cloudflareinsights.com"><link rel="preconnect" href="//www.clarity.ms"><link rel="preconnect" href="//busuanzi.ibruce.info"><link rel="preconnect" href="https://97MUPN4DMC-dsn.algolia.net" crossorigin=""><meta name="google-site-verification" content="tUkgeN6Ih2ArWtjw47oNSSl4Af2_MWjiKLrzZptUCdM"><meta name="msvalidate.01" content="71ADBCC80D679CEA8080BAFDCD54E368"><link rel="stylesheet" href="/css/index.css"><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@fortawesome/fontawesome-free/css/all.min.css"><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/node-snackbar/dist/snackbar.min.css" media="print" onload='this.media="all"'><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@fancyapps/ui/dist/fancybox/fancybox.css" media="print" onload='this.media="all"'><script>(()=>{const t={set:(e,t,a)=>{var o;0!==a&&(o=Date.now(),localStorage.setItem(e,JSON.stringify({value:t,expiry:o+864e5*a})))},get:e=>{var t=localStorage.getItem(e);if(t){t=JSON.parse(t);if(!(Date.now()>t.expiry))return t.value;localStorage.removeItem(e)}}},a=(window.btf={saveToLocal:t,getScript:(o,n={})=>new Promise((t,e)=>{const a=document.createElement("script");a.src=o,a.async=!0,a.onerror=e,a.onload=a.onreadystatechange=function(){var e=this.readyState;e&&"loaded"!==e&&"complete"!==e||(a.onload=a.onreadystatechange=null,t())},Object.keys(n).forEach(e=>{a.setAttribute(e,n[e])}),document.head.appendChild(a)}),getCSS:(o,n=!1)=>new Promise((t,e)=>{const a=document.createElement("link");a.rel="stylesheet",a.href=o,n&&(a.id=n),a.onerror=e,a.onload=a.onreadystatechange=function(){var e=this.readyState;e&&"loaded"!==e&&"complete"!==e||(a.onload=a.onreadystatechange=null,t())},document.head.appendChild(a)}),addGlobalFn:(e,t,a=!1,o=window)=>{var n=o.globalFn||{},d=n[e]||{};a&&d[a]||(d[a=a||Object.keys(d).length]=t,n[e]=d,o.globalFn=n)}},()=>{document.documentElement.setAttribute("data-theme","dark"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","#0d0d0d")}),o=()=>{document.documentElement.setAttribute("data-theme","light"),null!==document.querySelector('meta[name="theme-color"]')&&document.querySelector('meta[name="theme-color"]').setAttribute("content","ffffff")};btf.activateDarkMode=a,btf.activateLightMode=o;var e=t.get("theme"),n=window.matchMedia("(prefers-color-scheme: dark)").matches,d=window.matchMedia("(prefers-color-scheme: light)").matches,r=window.matchMedia("(prefers-color-scheme: no-preference)").matches,c=!n&&!d&&!r,n=(void 0===e?(d?o():n?a():(r||c)&&((d=(new Date).getHours())<=6||18<=d?a:o)(),window.matchMedia("(prefers-color-scheme: dark)").addListener(e=>{void 0===t.get("theme")&&(e.matches?a:o)()})):("light"===e?o:a)(),t.get("aside-status"));void 0!==n&&("hide"===n?document.documentElement.classList.add("hide-aside"):document.documentElement.classList.remove("hide-aside"));/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)&&document.documentElement.classList.add("apple")})()</script><script defer data-pjax="data-pjax" src="https://static.cloudflareinsights.com/beacon.min.js" data-cf-beacon="{&quot;token&quot;: &quot;35785b58f09f472ebfd7a2854973e6b8&quot;}"></script><script>!function(t,e,n,a,c,r){t[n]=t[n]||function(){(t[n].q=t[n].q||[]).push(arguments)},(c=e.createElement(a)).async=1,c.src="https://www.clarity.ms/tag/an4gdfm6a9",(r=e.getElementsByTagName(a)[0]).parentNode.insertBefore(c,r)}(window,document,"clarity","script")</script><script>const GLOBAL_CONFIG={postHeadAiDescription:{enable:!0,gptName:"CC",mode:"tianli",switchBtn:!0,btnLink:"https://tianli-blog.club/tianligpt/",randomNum:3,basicWordCount:1e3,key:"VCtoijR43E2uiVWkrZiC",Referer:"https://blog.ccknbc.cc/"},root:"/",algolia:void 0,localSearch:void 0,translate:{defaultEncoding:2,translateDelay:0,msgToTraditionalChinese:"繁",msgToSimplifiedChinese:"简"},noticeOutdate:{limitDay:15,position:"top",messagePrev:"本文最后一次更新为",messageNext:"天前，文章中的某些内容可能已过时！"},highlight:{plugin:"highlight.js",highlightCopy:!0,highlightLang:!0,highlightHeightLimit:!1,highlightFullpage:!0,highlightMacStyle:!0},copy:{success:"复制成功",error:"复制错误",noSupport:"浏览器不支持"},relativeDate:{homepage:!1,post:!1},runtime:"天",dateSuffix:{just:"刚刚",min:"分钟前",hour:"小时前",day:"天前",month:"个月前"},copyright:{limitCount:100,languages:{author:"作者: CC康纳百川",link:"链接: ",source:"来源: CC的部落格",info:"著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。"}},lightbox:"fancybox",Snackbar:{chs_to_cht:"你已切换为繁体中文",cht_to_chs:"你已切换为简体中文",day_to_night:"你已切换为深色模式",night_to_day:"你已切换为浅色模式",bgLight:"#49b1f5",bgDark:"#1f1f1f",position:"top-center"},infinitegrid:{js:"https://jsd.cdn.zzko.cn/npm/@egjs/infinitegrid/dist/infinitegrid.min.js",buttonText:"加载更多"},isPhotoFigcaption:!1,islazyload:!0,isAnchor:!1,percent:{toc:!0,rightside:!0},autoDarkmode:!0}</script><script id="config-diff">var GLOBAL_CONFIG_SITE={postAI:"本篇文章简单介绍了 Github Actions 的用法，以及一些变量的解释",pageFillDescription:"本文存在大量纰漏待修正, GitHub Actions 指南, 基本概念, runs-on amp strategy, runs-on 多环境, steps, action, checkout action, 引用 action, 引用公有库中的 action, 引用同一个库中的 action, 引用 Docker Hub 上的 container, 构建 actions, env, if amp context为什么这么香本文存在大量纰漏待修正为什么这么香我为什么专门建了一个组织来跑并储存博客源码或者其他只是单纯来跑的项目一开始就单纯只是想分类一堆主账号自己的项目却混在其中最新的反而是天天运行的排在前面而对大多数博主来说都是把自己的源码包含源文章仓库私有起来而一个普通账号每个月私有仓库运行时间为分钟确实是完全够用的对于我们这种月更博主来说一个月分钟而已好吧我就是懒不过作为白嫖党我还是公开了仓库这样就不限制运行时间了但如果你选择了定时执行某些项目注意间隔最小为分钟而触发方式也是多种多样的但最让人欣喜的是手动触发方式终于完成了技术革命不再监控动作了而是只有项目所有者可执行这样就不会再运行记录里出现一堆无关记录影响查看虽然之前判断仓库所有者也是但是强迫症不接受两秒运行跳过无关记录而且由于分配的临时机性能还不错速度还是很可观的并且不受长城防火墙的限制可以很方便的做一些其他事情这里就不细说回到标题它为什么这么香呢可能在工作流文件书写上没其他第三方简单用过或者的都应该有体会但自家的经过这么久的发展用起来还是比较舒服的而且用户编写的可以直接拿来用发布到市场这样有些功能的实现就不用再自己想半天去实现几行代码就搞定用写博客的都知道托管静态网页要更新的话就得手动点一下更新才行而就可以帮我们去点一下以实现同步全自动更新多平台部署本身自带的模板是的但毕竟很多新手完全不懂但其实上手一段时间就明白了每一步在做什么为什么要这样写官方文档的例子虽然很简单但确实是包含了常用的一些步骤再加上很多人分享直接拿来用就行毕竟搜索引擎不能摆在那不用爬几篇文章学习一下就会了这里我以部署博客为例来说一下首先我们得明白要让能在你上去后能自动部署博客你得知道博客的源文件是必须要的但备份哪些呢下图只是以本站做一个示例框中的是必须要有的如果你不打算修改主题源码其实也不用备份但毕竟可以节约时间第一次备份前记得在主题文件夹删掉隐藏文件夹不然推上去是空的会导致运行失败其他根据个人需求配一个证书或者等但你还在疑惑我没有文件夹啊没错这个就是我们自己新建的文件夹在博客根目录依次建立文件就像下图这样工作流文件你可以随便命名啦然后我们在工作流文件中添加如下内容手动触发你的用户名你的邮箱在文档流里我们可以用做权限认证是一个默认存在的变量并不需要我们去添加跨仓库的话还是要自己手动生成一个关于这点可以查看官方文档相关内容你可能有所疑惑但又看得懂一些命令别急请接着往下看指南使你可以直接在你的库中创建自定义的工作流工作流指的就是自动化的流程比如构建测试打包发布部署等等也就是说你可以直接进行持续集成和持续部署基本概念一个工作流就是一个完整的过程每个包含一组任务任务包含一个或多个每个包含一系列的步骤每个步骤可以执行指令或者使用一个动作每个动作就是一个通用的基本单元说明最外层的指定了的名称声明了一旦发生了操作就会触发这个定义了任务集其中可以有一个或多个任务示例中只有一个声明了运行的环境定义需要执行哪些步骤每个可以定义自己的和通过可以声明使用一个具体的通过声明需要执行哪些指令可以使用上下文参数声明了何时触发它可以是一个或多个事件比如了一个创建了一个产生了一次等等示例预定的时间示例每天零点零分触发不过因为时差关系是北京时间上午点某个外部事件所谓外部事件触发简而言之就是你可以通过向发送请求去触发具体请查阅官方文档配置多个事件示例详细文档请参考触发事件可以包含一个或多个如如果多个之间存在依赖关系那么你可能需要使用这里的声明了必须等待成功完成必须等待和依次成功完成每个任务默认超时时间最长为分钟你可以通过进行配置指定了任务的即执行环境分两种和所谓的就是用你自己的机器但是需要能进行访问并给与其所需的机器权限这个不在本文描述范围内有兴趣可参考其实就是提供的虚拟环境目前有以下四种或比较常见的多环境有时候我们常常需要对多个操作系统多个平台多个编程语言版本进行测试为此我们可以配置一个构建矩阵例如示例中配置了两种操作系统和三种版本即总共六种情况的构建矩阵是一个上下文参数策略包括构建矩阵默认为即一旦某个矩阵任务失败则立即取消所有还在进行中的任务可同时执行的最大并发数默认情况下会动态调整示例声明了为时增加一个和分别使用特定的版本的矩阵环境与相反的就是用来删除特定的配置项比如这里当为将为的版本从构建矩阵中移除的通用格式类似于每个步骤可以有每个步骤的唯一标识符步骤的名称使用哪个执行哪些指令指定某个可能需要输入的参数设置为允许此步骤失败仍然通过的超时时间动作通常是可以通用的这意味着你可以直接使用别人定义好的是一个标准动作当以下情况时必须且需要率先使用需要项目库的代码副本比如构建测试或持续集成这些操作中至少有一个是在同一个项目库下定义的使用示例如果你只想浅克隆你的库或者只复制最新的版本你可以在中使用声明例如引用官方标准库社区库引用公有库中的引用的格式是或例如上例的中你还可以使用标准库中的其它如设置版本引用同一个库中的引用格式或例如项目文件结构为当你想要在中引用自己的时可以引用上的如果某个定义在了一个中且推送到了上你也可以引入它格式是示例更多信息参考和构建请参考环境变量可以配置在以下地方示例如果重复优先使用最近的那个你可以在和中使用条件语句只有满足条件时才执行具体的或任务状态检查函数当上一步执行成功时返回总是返回当被取消时返回当上一步执行失败时返回例如意思就是总是执行需要上一步执行成功才执行只有当上一步执行失败才执行上下文和表达式有时候我们需要与第三方平台进行交互这时候通常需要配置一个但是显然这个不可能明文使用这种个情况下我们要做的就是在具体库的中添加一个密钥如注关于如何获取或者其他平台的密钥及授权不是本文重点大家可以自行百度然后在中就可以通过将安全地传递给环境变量这里的就是一个上下文除此之外还有很多比如触发的事件名称当前的状态如某个的输出的操作系统如这里只列举了少数几个另外在中使用时不需要符号比如上下文和表达式详细信息请参考看到这里你应该对示例文件有了一定的理解并且想自己去实验一下了那就去页面找到官方示例去体验一下吧但对于为什么要备份我想大家还是心存疑惑那我们看看具体内容吧我们看到里面包含了脚本和一些依赖包含版本的有了这个文件我们只需执行即可自动安装所以所需依赖插件而不用一个一个去敲一堆命令啦理解了这个简单的例子大家在部署其他项目时也许能更得心应手吧今天的分享就到这里结束了本文还有很多纰漏还请读者指出后续将更正下篇文章见",title:"Github Actions 为什么这么香",isPost:!0,isHome:!1,isHighlightShrink:!1,isToc:!0,postUpdate:"2020-10-06 12:00:00"}</script><script>"serviceWorker"in navigator&&(navigator.serviceWorker.register("/sw.js",{scope:"/"}).then(r=>{r.onupdatefound=()=>{const e=r.installing;e.onstatechange=()=>{"installed"===e.state&&(navigator.serviceWorker.controller?(void 0!==GLOBAL_CONFIG.Snackbar&&btf.snackbarShow("已刷新缓存，更新为最新内容"),navigator.serviceWorker.controller.postMessage({type:"skipWaiting"})):console.log("第一次注册Service Worker"))}}}),navigator.serviceWorker.addEventListener("message",e=>{e.data&&"refresh"===e.data.type&&(console.log("收到刷新页面请求，开始刷新页面"),window.location.reload())}))</script><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/hexo-butterfly-tag-plugins-plus/lib/assets/font-awesome-animation.min.css" media="defer" onload='this.media="all"'><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/hexo-butterfly-tag-plugins-plus/lib/tag_plugins.css" media="defer" onload='this.media="all"'><meta name="generator" content="Hexo 7.2.0"><link rel="alternate" href="/atom.xml" title="CC的部落格" type="application/atom+xml"><link rel="alternate" href="/rss.xml" title="CC的部落格" type="application/rss+xml"></head><body><script>window.paceOptions={restartOnPushState:!1},btf.addGlobalFn("pjaxSend",()=>{Pace.restart()},"pace_restart")</script><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/gh/CodeByZach/pace/themes/green/pace-theme-flash.css"><script src="https://jsd.cdn.zzko.cn/npm/pace-js/pace.min.js"></script><div id="web_bg"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img is-center"><img src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/logo.png" onerror='onerror=null,src="https://jsd.cdn.zzko.cn/npm/hexo-theme-anzhiyu/source/img/404.jpg"' alt="avatar"></div><div class="sidebar-site-data site-data is-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">38</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">7</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">7</div></a></div><hr class="custom-hr"><div class="menus_items"><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-book-reader"></i><span> 文章</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fa-solid fa-box-archive"></i><span> 归档</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fa-solid fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fa-solid fa-folder-open"></i><span> 分类</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-cubes"></i><span> 社交</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/blogroll/"><i class="fa-fw fa-solid fa-link"></i><span> 友链</span></a></li><li><a class="site-page child" href="/moments/"><i class="fa-fw fa-solid fa-blog"></i><span> 友圈</span></a></li><li><a class="site-page child" href="/music/"><i class="fa-fw fa-solid fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/essay/"><i class="fa-fw fa-solid fa-comment-alt"></i><span> 短文</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-desktop"></i><span> 关于</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/sub/"><i class="fa-fw fa-solid fa-bell"></i><span> 订阅</span></a></li><li><a class="site-page child" href="/about/"><i class="fa-fw fa-solid fa-list-check"></i><span> 本站</span></a></li><li><a class="site-page child" href="/privacy-policy/"><i class="fa-fw fa-solid fa-user-secret"></i><span> 隐私</span></a></li><li><a class="site-page child" target="_blank" rel="noopener external nofollow noreferrer" href="https://cc.instatus.com"><i class="fa-fw fa-solid fa-server"></i><span> 状态</span></a></li></ul></div></div></div></div><div class="post" id="body-wrap"><header class="post-bg" id="page-header" style="background-image:url(https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/731ab9880a63b4eb0d82d354cdbdadec_w2240_h1260_s743.jpg)"><nav id="nav"><span id="blog-info"><a href="/" title="CC的部落格"><span class="site-name">CC的部落格</span></a></span><div id="menus"><div id="search-button"><span class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></span></div><div class="menus_items"><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-book-reader"></i><span> 文章</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fa-solid fa-box-archive"></i><span> 归档</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fa-solid fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fa-solid fa-folder-open"></i><span> 分类</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-cubes"></i><span> 社交</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/blogroll/"><i class="fa-fw fa-solid fa-link"></i><span> 友链</span></a></li><li><a class="site-page child" href="/moments/"><i class="fa-fw fa-solid fa-blog"></i><span> 友圈</span></a></li><li><a class="site-page child" href="/music/"><i class="fa-fw fa-solid fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/essay/"><i class="fa-fw fa-solid fa-comment-alt"></i><span> 短文</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa-solid fa-desktop"></i><span> 关于</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/sub/"><i class="fa-fw fa-solid fa-bell"></i><span> 订阅</span></a></li><li><a class="site-page child" href="/about/"><i class="fa-fw fa-solid fa-list-check"></i><span> 本站</span></a></li><li><a class="site-page child" href="/privacy-policy/"><i class="fa-fw fa-solid fa-user-secret"></i><span> 隐私</span></a></li><li><a class="site-page child" target="_blank" rel="noopener external nofollow noreferrer" href="https://cc.instatus.com"><i class="fa-fw fa-solid fa-server"></i><span> 状态</span></a></li></ul></div></div><div id="toggle-menu"><span class="site-page"><i class="fas fa-bars fa-fw"></i></span></div></div></nav><div id="post-info"><h1 class="post-title">Github Actions 为什么这么香</h1><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2020-10-06T02:51:58.000Z" title="发表于 2020-10-06 10:51:58">2020-10-06</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2020-10-06T04:00:00.000Z" title="更新于 2020-10-06 12:00:00">2020-10-06</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/categories/%E5%B7%A5%E5%85%B7/">工具</a></span></div><div class="meta-secondline"><span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">4k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>16分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv" data-flag-title="Github Actions 为什么这么香"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"><i class="fa-solid fa-spinner fa-spin"></i></span></span></div></div></div></header><main class="layout" id="content-inner"><div id="post"><div class="post-ai-description"><div class="ai-title"><i class="fa-solid fa-newspaper"></i><div class="ai-title-text">AI-摘要</div><div id="ai-Toggle" title="CC/Tianli 模式切换">切换</div><i class="fa-solid fa-podcast" title="Tianli 模式下朗读摘要"></i><i class="fa-solid fa-arrow-rotate-right" title="Tianli 模式下刷新摘要"></i><div id="ai-tag">Tianli GPT</div></div><div class="ai-explanation">AI初始化中...</div><div class="ai-btn-box"><div class="ai-btn-item">介绍自己 🙈</div><div class="ai-btn-item">生成摘要 👋</div><div class="ai-btn-item">相关推荐 📖</div><div class="ai-btn-item">前往主页 🏠</div><div class="ai-btn-item" id="go-tianli-blog">前往爱发电购买</div></div><script data-pjax src="/"></script></div><article class="post-content" id="article-container"><p><a href="https://blog.ccknbc.cc/posts/why-github-actions-is-so-popular/">Github Actions 为什么这么香</a></p><h2 id="本文存在大量纰漏待修正">本文存在大量纰漏待修正<a class="fa-solid fa-hashtag" href="#本文存在大量纰漏待修正"></a></h2><p><code>Github Actions</code>为什么这么香,我为什么专门建了一个组织<code>ccknbc-actions</code>来跑 actions 并储存博客源码，或者其他只是单纯来跑 actions 的项目，一开始就单纯只是想分类，forked 一堆，主账号自己的项目却混在其中，最新的反而是天天运行 actions 的（排在前面）</p><p>而对大多数博主来说，都是把自己的源码（包含源文章）仓库私有起来，而一个普通账号每个月私有仓库运行时间为 2000 分钟，确实，是完全够用的，对于我们这种月更博主来说一个月 100 分钟而已（<s>好吧我就是懒</s>）；不过作为白嫖党我还是公开了仓库（这样就不限制运行时间了），但如果你选择了定时执行某些项目，注意间隔最小为<code>5分钟</code>，而触发方式也是多种多样的，但最让人欣喜的是手动触发方式终于完成了技术革命，不再监控 star 动作了，而是只有项目所有者可执行，这样就不会再运行记录里出现一堆无关记录影响查看（虽然之前判断仓库所有者也是 OK，但是强迫症不接受两秒运行跳过无关记录）</p><p>而且由于分配的临时机性能还不错，速度还是很可观的，并且不受长城防火墙的限制，可以很方便的做一些其他事情，这里就不细说，回到标题，它为什么这么香呢？</p><p>可能在工作流文件书写上没其他第三方简单，用过<code>Travis CI</code>或者<code>Gitlab CI</code>的都应该有体会，但自家的经过这么久的发展，用起来还是比较舒服的，而且用户编写的 actions 可以直接拿来用发布到市场，这样有些功能的实现就不用再自己想半天去实现，几行代码就搞定，用 HEXO 写博客的都知道 Gitee 托管静态网页要更新的话就得手动点一下更新才行，而 actions 就可以帮我们去点一下以实现同步全自动更新，多平台部署</p><p>Github 本身自带的模板是 OK 的，但毕竟很多新手完全不懂，但其实上手一段时间就明白了每一步在做什么为什么要这样写，官方文档的例子虽然很简单但确实是包含了常用的一些步骤，再加上很多人分享，直接拿来用就行，毕竟搜索引擎不能摆在那不用，爬几篇文章学习一下就会了，这里我以部署 HEXO 博客为例来说一下</p><p>首先我们得明白，要让 Github 能在你 git push 上去后能自动部署博客，你得知道博客的源文件是必须要的，但备份哪些呢，下图只是以本站做一个示例，框中的是必须要有的（如果你不打算修改主题源码其实也不用备份，但毕竟可以节约时间，第一次备份前记得在主题文件夹删掉<code>.git</code>隐藏文件夹，不然推上去是空的会导致运行失败），其他根据个人需求，，配一个证书或者 README 等，但你还在疑惑；我没有.github 文件夹啊，没错这个就是我们自己新建的文件夹，在博客根目录依次建立<code>.github/workflows/*.yml</code>文件</p><p><img src= "" data-lazy-src="https://cdn.jsdelivr.net/gh/ccknbc-backup/photos/blog/2020-10-06~11_57_17.webp#height=637&amp;id=Vyye0&amp;originHeight=637&amp;originWidth=744&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=744" alt="" loading="lazy"></p><p>就像下图这样，工作流文件.yml 你可以随便命名啦，然后我们在工作流文件中添加如下内容</p><p><img src= "" data-lazy-src="https://cdn.jsdelivr.net/gh/ccknbc-backup/photos/blog/2020-10-06~12_03_33.webp#height=119&amp;id=heF8i&amp;originHeight=119&amp;originWidth=329&amp;originalType=binary&amp;ratio=1&amp;rotation=0&amp;showTitle=false&amp;status=done&amp;style=none&amp;title=&amp;width=329" alt="" loading="lazy"></p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name:</span> <span class="string">Update</span> <span class="string">Blog</span> <span class="string">Butterfly</span> <span class="string">Site</span></span><br><span class="line"></span><br><span class="line"><span class="attr">on:</span></span><br><span class="line">  <span class="attr">push:</span></span><br><span class="line">    <span class="attr">branches:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">master</span></span><br><span class="line">  <span class="attr">workflow_dispatch:</span></span><br><span class="line">    <span class="attr">inputs:</span></span><br><span class="line">      <span class="attr">name:</span></span><br><span class="line">        <span class="attr">description:</span> <span class="string">&quot;手动触发&quot;</span></span><br><span class="line">        <span class="attr">required:</span> <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line">  <span class="attr">deploy:</span></span><br><span class="line">    <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line"></span><br><span class="line">    <span class="attr">steps:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Checkout</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/checkout@v2</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">ref:</span> <span class="string">master</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Setup</span> <span class="string">Node</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/setup-node@v2-beta</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">node-version:</span> <span class="string">&quot;12.x&quot;</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">HEXO</span> <span class="string">CI</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          npm install hexo-cli -g</span></span><br><span class="line"><span class="string"></span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Catch</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/cache@v2.1.1</span></span><br><span class="line">        <span class="attr">id:</span> <span class="string">cache-dependencies</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">path:</span> <span class="string">node_modules</span></span><br><span class="line">          <span class="attr">key:</span> <span class="string">$&#123;&#123;runner.OS&#125;&#125;-$&#123;&#123;hashFiles(&#x27;**/package-lock.json&#x27;)&#125;&#125;</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">Dependencies</span></span><br><span class="line">        <span class="attr">if:</span> <span class="string">steps.cache-dependencies.outputs.cache-hit</span> <span class="type">!=</span> <span class="string">&#x27;true&#x27;</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          npm install</span></span><br><span class="line"><span class="string"></span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Generate</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          hexo clean</span></span><br><span class="line"><span class="string">          git clone https://github.com/CCKNBC/butterfly.git public</span></span><br><span class="line"><span class="string">          hexo generate</span></span><br><span class="line"><span class="string">          gulp</span></span><br><span class="line"><span class="string"></span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Deploy</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          cd ./public</span></span><br><span class="line"><span class="string">          git config --global user.name &quot;你的用户名&quot;</span></span><br><span class="line"><span class="string">          git config --global user.email &quot;你的邮箱&quot;</span></span><br><span class="line"><span class="string">          git add -A</span></span><br><span class="line"><span class="string">          git commit -m &quot;Updated By Github Actions&quot;</span></span><br><span class="line"><span class="string">          git push --force --quiet &quot;https://ccknbc:$&#123;&#123; secrets.GH_TOKEN &#125;&#125;@github.com/ccknbc/butterfly.git&quot; master:master</span></span><br><span class="line"><span class="string">          git push --force --quiet &quot;https://ccknbc:$&#123;&#123; secrets.GT_TOKEN &#125;&#125;@gitee.com/ccknbc/butterfly.git&quot; master:master</span></span><br><span class="line"><span class="string">          git push --force --quiet &quot;https://$&#123;&#123; secrets.CD_USER &#125;&#125;:$&#123;&#123; secrets.CD_TOKEN &#125;&#125;@e.coding.net/ccknbc/blog/butterfly.git&quot; master:master</span></span><br><span class="line"><span class="string"></span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Build</span> <span class="string">Gitee</span> <span class="string">Pages</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">yanglbme/gitee-pages-action@master</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">gitee-username:</span> <span class="string">ccknbc</span></span><br><span class="line">          <span class="attr">gitee-password:</span> <span class="string">$&#123;&#123;</span> <span class="string">secrets.GITEE_PASSWORD</span> <span class="string">&#125;&#125;</span></span><br><span class="line">          <span class="attr">gitee-repo:</span> <span class="string">ccknbc/butterfly</span></span><br></pre></td></tr></table></figure><div class="note info icon flat"><p>在 workflow 文档流里我们可以用 <code>${{ secrets.GITHUB_TOKEN }}</code> 做权限认证，是一个默认存在的变量，并不需要我们去添加 ACCESS_TOKEN，跨仓库的话还是要自己手动生成一个，<a target="_blank" rel="noopener external nofollow noreferrer" href="https://docs.github.com/en/free-pro-team@latest/actions/reference/authentication-in-a-workflow#about-the-github_token-secret">关于这点，可以查看官方文档相关内容</a></p></div><p>你可能有所疑惑但又看得懂一些命令，别急，请接着往下看</p><h2 id="GitHub-Actions-指南">GitHub Actions 指南<a class="fa-solid fa-hashtag" href="#GitHub-Actions-指南"></a></h2><p><code>GitHub Actions</code>使你可以直接在你的<code>GitHub</code>库中创建自定义的工作流，工作流指的就是自动化的流程，比如构建、测试、打包、发布、部署等等，也就是说你可以直接进行 <code>CI</code>（持续集成）和 <code>CD</code>（持续部署）</p><h2 id="基本概念">基本概念<a class="fa-solid fa-hashtag" href="#基本概念"></a></h2><ol><li><code>workflow</code>: 一个 <code>workflow</code> 工作流就是一个完整的过程，每个<code>workflow</code> 包含一组 <code>jobs</code>任务</li><li><code>job : jobs</code>任务包含一个或多个<code>job</code> ，每个 <code>job</code>包含一系列的 <code>steps</code> 步骤</li><li><code>step</code> : 每个 <code>step</code> 步骤可以执行指令或者使用一个 <code>action</code> 动作</li><li><code>action</code> : 每个 <code>action</code> 动作就是一个通用的基本单元</li></ol><p>说明：</p><ol><li>最外层的 <code>name</code> 指定了 <code>workflow</code>的名称</li><li><code>on</code> 声明了一旦发生了 <code>push</code> 操作就会触发这个 <code>workflow</code></li><li><code>jobs</code>定义了任务集，其中可以有一个或多个<code>job</code> 任务，示例中只有一个</li><li><code>runs-on</code> 声明了运行的环境</li><li><code>steps</code>定义需要执行哪些步骤</li><li>每个 <code>step</code>可以定义自己的 <code>name</code>和<code>id</code>，通过 <code>uses</code> 可以声明使用一个具体的 <code>action</code>，通过<code>run</code> 声明需要执行哪些指令。</li><li>可以使用上下文参数<code>on</code> 声明了何时触发 <code>workflow</code>  ，它可以是：<ol><li>一个或多个<code>GitHub</code> 事件，比如 <code>push</code> 了一个 <code>commit</code> 、创建了一个<code>issue</code> ，产生了一次<code>pull request</code> 等等，示例：</li></ol></li></ol><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">on:[push,pull_request]</span></span><br></pre></td></tr></table></figure><ol><li>预定的时间，示例（每天零点零分触发，不过因为时差关系，是北京时间上午 8 点）：</li></ol><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">on:</span></span><br><span class="line">  <span class="attr">schedule:</span> <span class="string">-cron:&#x27;0</span> <span class="number">0</span> <span class="string">*</span> <span class="string">*</span> <span class="string">*&#x27;</span></span><br></pre></td></tr></table></figure><ol><li>某个外部事件。所谓外部事件触发，简而言之就是你可以通过<code>REST API</code>向 <code>GitHub</code> 发送请求去触发，具体请查阅官方文档: <code>repository-dispatch-event</code></li></ol><p>配置多个事件，示例：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">```yaml</span><br><span class="line">on:</span><br><span class="line"></span><br><span class="line"># Trigger the workflow on push or pull request,</span><br><span class="line"></span><br><span class="line"># but only for the master branch</span><br><span class="line"></span><br><span class="line">push:</span><br><span class="line"></span><br><span class="line">branches:</span><br><span class="line"></span><br><span class="line">- master</span><br><span class="line"></span><br><span class="line">pull_request:</span><br><span class="line"></span><br><span class="line">branches:</span><br><span class="line"></span><br><span class="line">- master</span><br><span class="line"></span><br><span class="line"># Also trigger on page_build, as well as release created events</span><br><span class="line"></span><br><span class="line">page_build:</span><br><span class="line"></span><br><span class="line">release:</span><br><span class="line"></span><br><span class="line">types: # This configuration does not affect the page_build event above</span><br><span class="line"></span><br><span class="line">- created</span><br></pre></td></tr></table></figure><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">详细文档请参考: 触发事件</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">## jobs</span><br><span class="line"></span><br><span class="line">`jobs`可以包含一个或多个 `job` ，如:</span><br><span class="line"></span><br><span class="line">```yaml</span><br><span class="line">jobs:</span><br><span class="line"></span><br><span class="line">my_first_job:</span><br><span class="line"></span><br><span class="line">name: My first job</span><br><span class="line"></span><br><span class="line">my_second_job:</span><br><span class="line"></span><br><span class="line">name: My second job</span><br></pre></td></tr></table></figure><p>如果多个<code>job</code> 之间存在依赖关系，那么你可能需要使用 <code>needs</code> :</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">jobs:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">job1:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">job2:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">needs:</span> <span class="string">job1</span></span><br><span class="line"></span><br><span class="line"><span class="attr">job3:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">needs:</span> [<span class="string">job1</span>, <span class="string">job2</span>]</span><br></pre></td></tr></table></figure><p>这里的<code>needs</code>声明了<code>job2</code> 必须等待 <code>job1</code> 成功完成，<code>job3</code>必须等待 <code>job1</code> 和 <code>job2</code>依次成功完成</p><p>每个任务默认超时时间最长为 <code>360</code>分钟，你可以通过 <code>timeout-minutes</code> 进行配置:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">jobs:</span></span><br><span class="line">	<span class="attr">job1:</span></span><br><span class="line">		<span class="attr">timeout-minutes:</span></span><br></pre></td></tr></table></figure><h2 id="runs-on-strategy">runs-on &amp; strategy<a class="fa-solid fa-hashtag" href="#runs-on-strategy"></a></h2><p><code>runs-on</code> 指定了任务的 <code>runner</code> 即执行环境，<code>runner</code> 分两种：<code>GitHub-hosted runner</code> 和 <code>self-hosted runner</code></p><p>所谓的 <code>self-hosted runner</code> 就是用你自己的机器，但是需要 <code>GitHub</code> 能进行访问并给与其所需的机器权限，这个不在本文描述范围内，有兴趣可参考 <code>self-hosted runner</code></p><p><code>GitHub-hosted runner</code> 其实就是 <code>GitHub</code> 提供的虚拟环境，目前有以下四种:</p><ol><li><code>windows-latest : Windows Server 2019</code></li><li><code>ubuntu-latest</code>或 <code>ubuntu-18.04</code></li><li><code>ubuntu-16.04</code> : <code>Ubuntu 16.04</code></li><li><code>macos-latest</code> : <code>macOS Catalina 10.15</code></li></ol><p>比较常见的:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">runs-on:ubuntu-latest</span></span><br></pre></td></tr></table></figure><h2 id="runs-on-多环境">runs-on 多环境<a class="fa-solid fa-hashtag" href="#runs-on-多环境"></a></h2><p>有时候我们常常需要对多个操作系统、多个平台、多个编程语言版本进行测试，为此我们可以配置一个构建矩阵</p><p>例如：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">runs-on:</span> <span class="string">$&#123;&#123;</span> <span class="string">matrix.os</span> <span class="string">&#125;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">strategy:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">matrix:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">os:</span> [<span class="string">ubuntu-16.04</span>, <span class="string">ubuntu-18.04</span>]</span><br><span class="line"></span><br><span class="line"><span class="attr">node:</span> [<span class="number">6</span>, <span class="number">8</span>, <span class="number">10</span>]</span><br></pre></td></tr></table></figure><p>示例中配置了两种<code>os</code>操作系统和三种 <code>node</code>版本即总共六种情况的构建矩阵， `${{matrix.os}}` 是一个上下文参数</p><p><code>strategy</code> 策略，包括：</p><ol><li><code>matrix</code>: 构建矩阵</li><li><code>fail-fast</code> : 默认为<code>true</code> ，即一旦某个矩阵任务失败则立即取消所有还在进行中的任务</li><li><code>max-paraller</code> : 可同时执行的最大并发数，默认情况下 <code>GitHub</code> 会动态调整</li></ol><p>示例：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">runs-on:</span> <span class="string">$&#123;&#123;</span> <span class="string">matrix.os</span> <span class="string">&#125;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">strategy:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">matrix:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">os:</span> [<span class="string">macos-latest</span>, <span class="string">windows-latest</span>, <span class="string">ubuntu-18.04</span>]</span><br><span class="line"></span><br><span class="line"><span class="attr">node:</span> [<span class="number">4</span>, <span class="number">6</span>, <span class="number">8</span>, <span class="number">10</span>]</span><br><span class="line"></span><br><span class="line"><span class="attr">include:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># includes a new variable of npm with a value of 2 for the matrix leg matching the os and version</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">os:</span> <span class="string">windows-latest</span></span><br><span class="line"></span><br><span class="line"><span class="attr">node:</span> <span class="number">4</span></span><br><span class="line"></span><br><span class="line"><span class="attr">npm:</span> <span class="number">2</span></span><br></pre></td></tr></table></figure><p><code>include</code>声明了 <code>os</code> 为 <code>windows-latest</code> 时，增加一个 <code>node</code>和<code>npm</code>分别使用特定的版本的矩阵环境</p><p>与<code>include</code> 相反的就是<code>exclude</code> ：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">runs-on:</span> <span class="string">$&#123;&#123;</span> <span class="string">matrix.os</span> <span class="string">&#125;&#125;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">strategy:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">matrix:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">os:</span> [<span class="string">macos-latest</span>, <span class="string">windows-latest</span>, <span class="string">ubuntu-18.04</span>]</span><br><span class="line"></span><br><span class="line"><span class="attr">node:</span> [<span class="number">4</span>, <span class="number">6</span>, <span class="number">8</span>, <span class="number">10</span>]</span><br><span class="line"></span><br><span class="line"><span class="attr">exclude:</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># excludes node 4 on macOS</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">os:</span> <span class="string">macos-latest</span></span><br><span class="line"></span><br><span class="line"><span class="attr">node:</span> <span class="number">4</span></span><br></pre></td></tr></table></figure><p><code>exclude</code> 用来删除特定的配置项，比如这里当<code>os</code> 为 <code>macos-latest</code>，将 <code>node</code>为 4 的版本从构建矩阵中移除</p><h2 id="steps">steps<a class="fa-solid fa-hashtag" href="#steps"></a></h2><p><code>steps</code> 的通用格式类似于：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">steps:</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">&lt;step_name&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">uses:</span> <span class="string">&lt;action&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">with:</span></span><br><span class="line"></span><br><span class="line"><span class="string">&lt;parameter_name&gt;:</span> <span class="string">&lt;parameter_value&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">id:</span> <span class="string">&lt;step_id&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">continue-on-error:</span> <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">&lt;step_name&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">timeout-minutes:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">run:</span> <span class="string">&lt;commands&gt;</span></span><br></pre></td></tr></table></figure><p>每个 <code>step</code> 步骤可以有:</p><ol><li><code>id</code> : 每个步骤的唯一标识符</li><li><code>name</code> : 步骤的名称</li><li><code>uses</code> : 使用哪个<code>action</code></li><li><code>run</code>: 执行哪些指令</li><li><code>with</code>: 指定某个<code>action</code> 可能需要输入的参数</li><li><code>continue-on-error</code> : 设置为 <code>true</code> 允许此步骤失败<code>job</code> 仍然通过</li><li><code>timeout-minutes : step</code> 的超时时间</li></ol><h2 id="action">action<a class="fa-solid fa-hashtag" href="#action"></a></h2><p><code>action</code> 动作通常是可以通用的，这意味着你可以直接使用别人定义好的<code>action</code></p><h2 id="checkout-action">checkout action<a class="fa-solid fa-hashtag" href="#checkout-action"></a></h2><p><code>checkout action</code> 是一个标准动作，当以下情况时必须且需要率先使用:</p><ol><li><code>workflow</code> 需要项目库的代码副本，比如构建、测试、或持续集成这些操作</li><li><code>workflow</code> 中至少有一个 <code>action</code>是在同一个项目库下定义的</li></ol><p>使用示例：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="string">users:action/checkout@v1</span></span><br></pre></td></tr></table></figure><p>如果你只想浅克隆你的库，或者只复制最新的版本，你可以在 <code>with</code>中使用<code>fetch-depth</code>声明，例如:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="string">user:action/checkout@v1</span></span><br><span class="line">  <span class="attr">with:</span></span><br><span class="line">  	<span class="string">fetch-depth:1</span></span><br></pre></td></tr></table></figure><h2 id="引用-action">引用 action<a class="fa-solid fa-hashtag" href="#引用-action"></a></h2><ol><li>官方<code>action</code>标准库: <a target="_blank" rel="noopener external nofollow noreferrer" href="http://github.com/actions">github.com/actions</a></li><li>社区库:<code>marketplace</code></li></ol><h2 id="引用公有库中的-action">引用公有库中的 action<a class="fa-solid fa-hashtag" href="#引用公有库中的-action"></a></h2><p>引用 <code>action</code> 的格式是<code>&#123;owner&#125;/&#123;repo&#125;@&#123;ref&#125;</code>或 <code>&#123;owner&#125;/&#123;repo&#125;/&#123;path&#125;@&#123;ref&#125;</code>，例如上例的中<code>actions/checkout@v1</code>，你还可以使用标准库中的其它 <code>action</code>，如设置 <code>node</code> 版本:</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">jobs:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">my_first_job:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">name:</span> <span class="string">My</span> <span class="string">Job</span> <span class="string">Name</span></span><br><span class="line"></span><br><span class="line"><span class="attr">steps:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/setup-node@v1</span></span><br><span class="line"></span><br><span class="line"><span class="attr">with:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">node-version:</span> <span class="number">10.</span><span class="string">x</span></span><br></pre></td></tr></table></figure><h2 id="引用同一个库中的-action">引用同一个库中的 action<a class="fa-solid fa-hashtag" href="#引用同一个库中的-action"></a></h2><p>引用格式：<code>&#123;owner&#125;/&#123;repo&#125;@&#123;ref&#125;</code>或 <code>./path/to/dir</code></p><p>例如项目文件结构为：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">--</span> <span class="string">hello-world</span> <span class="string">(repository)</span></span><br><span class="line"></span><br><span class="line"><span class="string">|__</span> <span class="string">.github</span></span><br><span class="line"></span><br><span class="line"><span class="string">└──</span> <span class="string">workflows</span></span><br><span class="line"></span><br><span class="line"><span class="string">└──</span> <span class="string">my-first-workflow.yml</span></span><br><span class="line"></span><br><span class="line"><span class="string">└──</span> <span class="string">actions</span></span><br><span class="line"></span><br><span class="line"><span class="string">|__</span> <span class="string">hello-world-action</span></span><br><span class="line"></span><br><span class="line"><span class="string">└──</span> <span class="string">action.yml</span></span><br></pre></td></tr></table></figure><p>当你想要在<code>workflow</code> 中引用自己的<code>action</code> 时可以：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">jobs:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">build:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line"></span><br><span class="line"><span class="attr">steps:</span></span><br><span class="line">  <span class="comment"># This step checks out a copy of your repository.</span></span><br><span class="line"></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/checkout@v1</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># This step references the directory that contains the action.</span></span><br><span class="line"></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">./.github/actions/hello-world-action</span></span><br></pre></td></tr></table></figure><h2 id="引用-Docker-Hub-上的-container">引用 Docker Hub 上的 container<a class="fa-solid fa-hashtag" href="#引用-Docker-Hub-上的-container"></a></h2><p>如果某个 <code>action</code> 定义在了一个<code>docker container image</code> 中且推送到了<code>Docker Hub</code> 上，你也可以引入它，格式是<code>docker://&#123;image&#125;:&#123;tag&#125;</code> ，示例：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">jobs:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">my_first_job:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">steps:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">My</span> <span class="string">first</span> <span class="string">step</span></span><br><span class="line"></span><br><span class="line"><span class="attr">uses:</span> <span class="string">docker://alpine:3.8</span></span><br></pre></td></tr></table></figure><p>更多信息参考:<code>Docker-image.yml workflow</code> 和<code>Creating a Docker container ``action</code></p><h2 id="构建-actions">构建 actions<a class="fa-solid fa-hashtag" href="#构建-actions"></a></h2><p>请参考：<code>building-actions</code></p><h2 id="env">env<a class="fa-solid fa-hashtag" href="#env"></a></h2><p>环境变量可以配置在以下地方:</p><ol><li><code>env</code></li><li><code>jobs.&lt;job_id&gt;.env</code></li><li><code>jobs.&lt;job_id&gt;.steps.env</code></li></ol><p>示例：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">env:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">NODE_ENV:</span> <span class="string">dev</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">job1:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">env:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">NODE_ENV:</span> <span class="string">test</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="attr">steps:</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">env:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">NODE_ENV:</span> <span class="string">prod</span></span><br></pre></td></tr></table></figure><p>如果重复，优先使用最近的那个</p><h2 id="if-context">if &amp; context<a class="fa-solid fa-hashtag" href="#if-context"></a></h2><p>你可以在 <code>job</code>和<code>step</code>中使用<code>if</code>条件语句，只有满足条件时才执行具体的<code>job</code> 或 <code>step</code> :</p><ol><li><code>jobs.&lt;job_id&gt;.if</code></li><li><code>jobs.&lt;job_id&gt;.steps.if</code></li></ol><p>任务状态检查函数:</p><ol start="3"><li><code>success()</code> : 当上一步执行成功时返回 <code>true</code></li><li><code>always()</code> : 总是返回 <code>true</code></li><li><code>cancelled()</code> : 当 <code>workflow</code>被取消时返回 <code>true</code></li><li><code>failure()</code> : 当上一步执行失败时返回 <code>true</code></li></ol><p>例如：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">steps:</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">step1</span></span><br><span class="line"></span><br><span class="line"><span class="attr">if:</span> <span class="string">always()</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">step2</span></span><br><span class="line"></span><br><span class="line"><span class="attr">if:</span> <span class="string">success()</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">step3</span></span><br><span class="line"></span><br><span class="line"><span class="attr">if:</span> <span class="string">failure()</span></span><br></pre></td></tr></table></figure><p>意思就是 <code>step1</code>总是执行，<code>step2</code> 需要上一步执行成功才执行，<code>step3</code> 只有当上一步执行失败才执行</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="string">$&#123;&#123;&lt;expression&gt;&#125;&#125;</span></span><br></pre></td></tr></table></figure><p>上下文和表达式: <code>$&#123;&#123;<expression>&#125;&#125;</expression></code></p><p>有时候我们需要与第三方平台进行交互，这时候通常需要配置一个<code>token</code>，但是显然这个 <code>token</code> 不可能明文使用，这种个情况下我们要做的就是：</p><ol><li>在具体 <code>repository</code> 库<code>Settings</code> 的 <code>Secrets</code> 中添加一个密钥，如 <code>SOMEONE_TOKEN</code></li></ol><div class="note warning flat"><p>注：关于如何获取 github 或者其他平台的密钥及授权不是本文重点，大家可以自行百度</p></div><ol start="2"><li>然后在<code>workflow</code>中就可以通过 <code>$&#123;&#123;secrets.SOMEONE_TOKEN&#125;&#125;</code> 将 <code>token</code>安全地传递给环境变量</li></ol><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">steps:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">My</span> <span class="string">first</span> <span class="string">action</span></span><br><span class="line"></span><br><span class="line"><span class="attr">env:</span></span><br><span class="line"></span><br><span class="line"><span class="attr">SOMEONE_TOKEN:</span> <span class="string">$&#123;&#123;</span> <span class="string">secrets.SOMEONE_TOKEN</span> <span class="string">&#125;&#125;</span></span><br></pre></td></tr></table></figure><p>这里的<code>secrets</code> 就是一个上下文，除此之外还有很多，比如：</p><ol><li><code>github.event_name</code> : 触发<code>workflow</code>的事件名称</li><li><code>job.status</code> : 当前<code>job</code> 的状态，如 <code>success, failure, or cancelled</code></li><li><code>steps.&lt;step id&gt;.outputs</code> : 某个 <code>action</code> 的输出</li><li><code>runner.os : runner</code>的操作系统如 <code>Linux, Windows, or macOS</code></li></ol><p>这里只列举了少数几个</p><p>另外在<code>if</code> 中使用时不需要 <code>$&#123;&#123;&#125;&#125;</code> 符号，比如：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">steps:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">My</span> <span class="string">first</span> <span class="string">step</span></span><br><span class="line"></span><br><span class="line"><span class="attr">if:</span> <span class="string">github.event_name</span> <span class="string">==</span> <span class="string">&#x27;pull_request&#x27;</span> <span class="string">&amp;&amp;</span> <span class="string">github.event.action</span> <span class="string">==</span> <span class="string">&#x27;unassigned&#x27;</span></span><br><span class="line"></span><br><span class="line"><span class="attr">run:</span> <span class="string">echo</span> <span class="string">This</span> <span class="string">event</span> <span class="string">is</span> <span class="string">a</span> <span class="string">pull</span> <span class="string">request</span> <span class="string">that</span> <span class="string">had</span> <span class="string">an</span> <span class="string">assignee</span> <span class="string">removed.</span></span><br></pre></td></tr></table></figure><p>上下文和表达式详细信息请参考：<code>contexts-and-expression</code></p><p>看到这里你应该对示例文件有了一定的理解，并且想自己去实验一下了，那就去 actions 页面找到官方示例去体验一下吧</p><p>但对于为什么要备份<code>package.json</code>我想大家还是心存疑惑，那我们看看具体内容吧</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;name&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hexo-site&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;0.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;private&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;scripts&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;build&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hexo generate&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;clean&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hexo clean&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;deploy&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hexo deploy&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;server&quot;</span><span class="punctuation">:</span> <span class="string">&quot;hexo server&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;hexo&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;version&quot;</span><span class="punctuation">:</span> <span class="string">&quot;5.2.0&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;dependencies&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;cheerio&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^1.0.0-rc.3&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;gulp-htmlmin&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^5.0.1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^5.2.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-baidupush&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^1.0.2&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-charts&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^1.0.3&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-cli&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^4.2.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-deployer-git&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^2.1.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-generator-archive&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^1.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-generator-baidu-sitemap&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^0.1.9&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-generator-category&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^1.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-generator-feed&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^3.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-generator-index&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^2.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-generator-search&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^2.4.1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-generator-sitemap&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^2.1.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-generator-tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^1.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-render-pug&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^2.1.4&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-renderer-ejs&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^1.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-renderer-marked&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^3.3.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-renderer-pug&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^1.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-renderer-stylus&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^2.0.1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-server&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^2.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-tag-aplayer&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^3.0.4&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;hexo-wordcount&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^6.0.1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;pump&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^3.0.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;terser&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^4.8.0&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;devDependencies&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;gulp&quot;</span><span class="punctuation">:</span> <span class="string">&quot;4.0.2&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;gulp-cli&quot;</span><span class="punctuation">:</span> <span class="string">&quot;2.3.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;gulp-clean-css&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^4.3.0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;gulp-htmlclean&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^2.7.22&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;gulp-uglify&quot;</span><span class="punctuation">:</span> <span class="string">&quot;^3.0.2&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>我们看到里面包含了 npm 脚本和一些依赖（包含 dev 版本的），有了这个文件我们只需执行 npm i(install)即可自动安装所以所需依赖插件，而不用一个一个去敲一堆命令啦，理解了这个简单的例子，大家在部署其他项目时也许能更得心应手吧</p><p>今天的分享就到这里结束了，本文还有很多纰漏还请读者指出，后续将更正，下篇文章见</p></article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta"><i class="fas fa-circle-user fa-fw"></i>文章作者: </span><span class="post-copyright-info"><a href="https://blog.ccknbc.cc/">CC康纳百川</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta"><i class="fas fa-square-arrow-up-right fa-fw"></i>文章链接: </span><span class="post-copyright-info"><a href="https://blog.ccknbc.cc/posts/why-github-actions-is-so-popular/">https://blog.ccknbc.cc/posts/why-github-actions-is-so-popular/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta"><i class="fas fa-circle-exclamation fa-fw"></i>版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a target="_blank" rel="noopener external nofollow noreferrer" href="https://creativecommons.org/licenses/by-nc-sa/4.0/"><i style="color:#8fbc8f" class="fa-brands fa-creative-commons"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-by"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-nc"></i> <i style="color:#8fbc8f" class="fa-brands fa-creative-commons-sa"></i> CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://blog.ccknbc.cc">CC的部落格</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/%E5%B7%A5%E5%85%B7/">工具</a></div><div class="post_share"><div class="social-share" data-image="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/731ab9880a63b4eb0d82d354cdbdadec_w2240_h1260_s743.jpg" data-sites="wechat,weibo,qq,facebook,twitter"></div><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/butterfly-extsrc/sharejs/dist/css/share.min.css" media="print" onload='this.media="all"'><script src="https://jsd.cdn.zzko.cn/npm/butterfly-extsrc/sharejs/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i>赞赏</div><div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="https://www.rocschool.com/tool/qr/qr/id/51.html" rel="external nofollow noreferrer" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/qr.png" alt="三合一"></a><div class="post-qr-code-desc">三合一</div></li><li class="reward-item"><a href="https://afdian.net/@ccknbc" rel="external nofollow noreferrer" target="_blank"><img class="post-qr-code-img" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/afdian.png" alt="爱发电"></a><div class="post-qr-code-desc">爱发电</div></li></ul></div></div><nav class="pagination-post" id="pagination"><div class="prev-post pull-left"><a href="/posts/why-did-i-choose-tidio-as-the-chat-system/" title="我为什么选择了 Tidio 做聊天系统"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/374954d02e9ba8b6387616ae3029b4b9_w2240_h1260_s757.jpg" onerror='onerror=null,src="https://jsd.cdn.zzko.cn/npm/hexo-theme-anzhiyu/source/img/friend_404.gif"' alt="cover of previous post"><div class="pagination-info"><div class="label">上一篇</div><div class="prev_info">我为什么选择了 Tidio 做聊天系统</div></div></a></div><div class="next-post pull-right"><a href="/posts/how-to-enjoy-joox-music-service-in-mainland-china/" title="如何在中国大陆享受 JOOX 音乐服务"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/c45d99fe170ead3b6d12b103e320b732_w2560_h1440_s636.jpg" onerror='onerror=null,src="https://jsd.cdn.zzko.cn/npm/hexo-theme-anzhiyu/source/img/friend_404.gif"' alt="cover of next post"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">如何在中国大陆享受 JOOX 音乐服务</div></div></a></div></nav><div class="relatedPosts"><div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>相关推荐</span></div><div class="relatedPosts-list"><div><a href="/posts/hexo-webpushr-notification/" title="Hexo浏览器定向推送文章更新"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/d2a947d48815ed24936a919873b97841_w1366_h768_s31.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-10-05</div><div class="title">Hexo浏览器定向推送文章更新</div></div></a></div><div><a href="/posts/the-real-addthis/" title="你以为 AddThis 只是个分享工具吗？"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/bbf0970587cfd0f4a654efda9c375844_w1920_h1080_s216.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-05-15</div><div class="title">你以为 AddThis 只是个分享工具吗？</div></div></a></div><div><a href="/posts/hexo-butterfly-algolia/" title="Hexo Butterfly Algolia 搜索的使用"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/c9dcd19b9621a425f914ffb64cf2f8c1_w1920_h1080_s281.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-05-11</div><div class="title">Hexo Butterfly Algolia 搜索的使用</div></div></a></div><div><a href="/posts/yuque-to-hexo/" title="语雀文章同步至Hexo笔记"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/721e476cb2661152b9c43621c94e3ed7_w1366_h768_s86.png" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2022-10-04</div><div class="title">语雀文章同步至Hexo笔记</div></div></a></div><div><a href="/posts/2fa-last-security-line/" title="两步验证 最后一道安全防线"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/0d0f43b526a6944a65566a2fd7aa9939_w1920_h1080_s214.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-11-21</div><div class="title">两步验证 最后一道安全防线</div></div></a></div><div><a href="/posts/waline-comments-system-deployment-logs/" title="Waline 评论系统部署日志"><img class="cover" src= "" data-lazy-src="https://pic1.afdiancdn.com/user/8a7f563c2e3811ecab5852540025c377/common/edd977e4a8569283e89ac7426b67dfc3_w1920_h1080_s366.jpg" alt="cover"><div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> 2021-01-17</div><div class="title">Waline 评论系统部署日志</div></div></a></div></div></div><hr class="custom-hr"><div id="post-comment"><div class="comment-head"><div class="comment-headline"><i class="fas fa-comments fa-fw"></i><span> 评论</span></div></div><div class="comment-wrap"><div><div id="waline-wrap"></div></div></div></div></div><div class="aside-content" id="aside-content"><div class="sticky_layout"><div class="card-widget" id="card-toc"><div class="item-headline"><i class="fas fa-stream"></i><span>目录</span><span class="toc-percentage"></span></div><div class="toc-content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9C%AC%E6%96%87%E5%AD%98%E5%9C%A8%E5%A4%A7%E9%87%8F%E7%BA%B0%E6%BC%8F%E5%BE%85%E4%BF%AE%E6%AD%A3"><span class="toc-number">1.</span> <span class="toc-text">本文存在大量纰漏待修正</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#GitHub-Actions-%E6%8C%87%E5%8D%97"><span class="toc-number">2.</span> <span class="toc-text">GitHub Actions 指南</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5"><span class="toc-number">3.</span> <span class="toc-text">基本概念</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#runs-on-strategy"><span class="toc-number">4.</span> <span class="toc-text">runs-on &amp; strategy</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#runs-on-%E5%A4%9A%E7%8E%AF%E5%A2%83"><span class="toc-number">5.</span> <span class="toc-text">runs-on 多环境</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#steps"><span class="toc-number">6.</span> <span class="toc-text">steps</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#action"><span class="toc-number">7.</span> <span class="toc-text">action</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#checkout-action"><span class="toc-number">8.</span> <span class="toc-text">checkout action</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BC%95%E7%94%A8-action"><span class="toc-number">9.</span> <span class="toc-text">引用 action</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BC%95%E7%94%A8%E5%85%AC%E6%9C%89%E5%BA%93%E4%B8%AD%E7%9A%84-action"><span class="toc-number">10.</span> <span class="toc-text">引用公有库中的 action</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BC%95%E7%94%A8%E5%90%8C%E4%B8%80%E4%B8%AA%E5%BA%93%E4%B8%AD%E7%9A%84-action"><span class="toc-number">11.</span> <span class="toc-text">引用同一个库中的 action</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%BC%95%E7%94%A8-Docker-Hub-%E4%B8%8A%E7%9A%84-container"><span class="toc-number">12.</span> <span class="toc-text">引用 Docker Hub 上的 container</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9E%84%E5%BB%BA-actions"><span class="toc-number">13.</span> <span class="toc-text">构建 actions</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#env"><span class="toc-number">14.</span> <span class="toc-text">env</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#if-context"><span class="toc-number">15.</span> <span class="toc-text">if &amp; context</span></a></li></ol></div></div></div></div></main><footer id="footer" style="background:linear-gradient(135deg,#fff1eb,#ace0f9)"><div id="footer-wrap"><div class="icp"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://beian.miit.gov.cn"><img class="icp-icon" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/icp.png" alt="ICP"><span>鄂 ICP 备 2020019764 号</span></a></div><div class="gongan"><a target="_blank" rel="noopener external nofollow noreferrer" href="https://www.beian.gov.cn/portal/registerSystemInfo?recordcode=42088102000092"><img class="gongan-icon" src= "" data-lazy-src="https://jsd.cdn.zzko.cn/gh/ccknbc-backup/cdn/logo/gongan.png" alt="gongan"><span>鄂公网安备 42088102000092 号</span></a></div><div class="live"><span>本站已运行</span><span id="display_live"></span><span class="moe-text">CCKNBC All Rights Reserved.</span><script>function blog_live(){window.setTimeout(blog_live,1e3);var e=new Date("2020-06-04T00:00:00"),o=new Date,l=o.getFullYear(),o=o.getTime()-e.getTime(),e=864e5,t=365*e,i=Math.floor(o/t),t=Math.floor(o%t/e),e=Math.floor(o%e/60/60/1e3),a=Math.floor(o%36e5/60/1e3),o=Math.floor(o%6e4/1e3);display_live.innerHTML=" "+i+" 年 "+t+" 天 "+e+" 小时 "+a+" 分 "+o+" 秒<br>&copy; 2020 - "+l+" "}blog_live()</script></div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><a class="edit-yuque" target="_blank" rel="noopener external nofollow noreferrer" href="https://www.yuque.com/ccknbc/blog/-9/edit/" title="在语雀上以富文本格式编辑/预览 - Github Actions 为什么这么香"><i class="fa-solid fa-crow"></i></a><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fa-solid fa-arrows-alt-h"></i></button><button id="readmode" type="button" title="阅读模式"><i class="fa-solid fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fa-solid fa-adjust"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="设置"><i class="fa-solid fa-cog"></i></button><button id="share-link" type="button" title="分享链接"><i class="fa-solid fa-share"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fa-solid fa-list-ul"></i></button><a id="to_comment" href="#post-comment" title="直达评论"><i class="fa-solid fa-comments"></i></a><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fa-solid fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js"></script><script src="/js/main.js"></script><script src="/js/tw_cn.js"></script><script src="https://jsd.cdn.zzko.cn/npm/@fancyapps/ui/dist/fancybox/fancybox.umd.js"></script><script src="https://jsd.cdn.zzko.cn/npm/instant.page/instantpage.js" type="module"></script><script src="https://jsd.cdn.zzko.cn/npm/vanilla-lazyload/dist/lazyload.iife.min.js"></script><script src="https://jsd.cdn.zzko.cn/npm/node-snackbar/dist/snackbar.min.js"></script><div class="js-pjax"><script>(()=>{var e=()=>{var e;const t=document.querySelectorAll("#article-container .mermaid-wrap");0!==t.length&&(e=()=>{{var e=t;window.loadMermaid=!0;const a="dark"===document.documentElement.getAttribute("data-theme")?"dark":"default";Array.from(e).forEach((e,t)=>{const n=e.firstElementChild;e="%%{init:{ 'theme':'"+a+"'}}%%\n"+n.textContent;const d=mermaid.render("mermaid-"+t,e);"string"==typeof d?(t=d,n.insertAdjacentHTML("afterend",t)):d.then(({svg:e})=>{n.insertAdjacentHTML("afterend",e)})})}},btf.addGlobalFn("themeChange",e,"mermaid"),window.loadMermaid?e():btf.getScript("https://jsd.cdn.zzko.cn/npm/mermaid/dist/mermaid.min.js").then(e))};btf.addGlobalFn("encrypt",e,"mermaid"),window.pjax?e():document.addEventListener("DOMContentLoaded",e)})()</script><script>(()=>{let n=window.walineFn||null;const t=e=>{const n=e(Object.assign({el:"#waline-wrap",serverURL:"https://waline.ccknbc.cc",pageview:!1,dark:'html[data-theme="dark"]',path:window.location.pathname,comment:!1,imageUploader:function(e){var n=new FormData,t=new Headers;return n.append("file",e),n.append("album_id","10"),n.append("permission","0"),t.append("Authorization","Bearer 24|o8Crl5y0oK3luyUs17fBxDtAcevk1iiLHVFMNjpA"),t.append("Accept","application/json"),fetch("https://wmimg.com/api/v1/upload",{method:"POST",headers:t,body:n}).then(e=>e.json()).then(e=>e.data.links.url)}},{pageSize:10,meta:["nick","mail","link"],requiredMeta:["nick","mail"],login:"force",copyright:!0,search:!0,turnstileKey:"0x4AAAAAAAECBl27OB5SZrQT",locale:{admin:"博主",sofa:"这里冷冷清清的，快来留下脚印吧！",placeholder:"根据《互联网跟帖评论服务管理规定》，将展示您的归属地，并开启强制注册登录后才允许评论\n社交登录现已支持【QQ Weibo GitHub X Facebook】等平台，登录后可点击头像更改个人主页地址，方便CC串门\n在评论框粘贴图片，自动上传至图床，请不要将评论区作为您的图床，更不要上传违法图片，谢谢合作",reactionTitle:"就现在，表明你的态度！",reaction0:"鼓励",reaction1:"菜狗",reaction2:"正确",reaction3:"错误",reaction4:"思考",reaction5:"无聊",level0:"买菜",level1:"切菜",level2:"炒菜",level3:"煲汤",level4:"煮面",level5:"上桌",level6:"开吃"},emoji:["https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/"],reaction:["https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/鼓掌.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/菜狗.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/正确.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/错误.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/思考.png","https://jsd.cdn.zzko.cn/npm/sticker-heo/Sticker-100/睡觉.png"]}));btf.addGlobalFn("pjax",()=>{n.destroy()},"destroyWaline")};var e=()=>{n?t(n):(btf.getCSS("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline.css"),btf.getCSS("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline-meta.css").then(()=>import("https://jsd.cdn.zzko.cn/npm/@waline/client/dist/waline.js")).then(({init:e})=>{n=e||Waline.init,t(n),window.walineFn=n}))};btf.loadComment(document.getElementById("waline-wrap"),e)})()</script></div><script>window.addEventListener("load",()=>{const t=e=>e=""!==e&&150<(e=(e=(e=(e=e.replace(/<img.*?src="(.*?)"?[^\>]+>/gi,"[图片]")).replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi,"[链接]")).replace(/<pre><code>.*?<\/pre>/gi,"[代码]")).replace(/<[^>]+>/g,"")).length?e.substring(0,150)+"...":e,a=t=>{let a="";if(t.length)for(let e=0;e<t.length;e++)a=(a+="<div class='aside-list-item'>")+`<div class='content'>
        <a class='comment' href='${t[e].url}' title='${t[e].content}'>${t[e].content}</a>
        <div class='name'><span>${t[e].nick} / </span><time datetime="${t[e].date}">${btf.diffDate(t[e].date,!0)}</time></div>
        </div></div>`;else a+="没有评论";var e=document.querySelector("#card-newest-comments .aside-list");e&&(e.innerHTML=a),window.lazyLoadInstance&&window.lazyLoadInstance.update(),window.pjax&&window.pjax.refresh(e)};var e=()=>{var e;document.querySelector("#card-newest-comments .aside-list")&&((e=btf.saveToLocal.get("waline-newest-comments"))?a(JSON.parse(e)):(async()=>{try{var e=(await(await fetch("https://waline.ccknbc.cc/api/comment?type=recent&count=3",{method:"GET"})).json()).data.map(e=>({content:t(e.comment),avatar:e.avatar,nick:e.nick,url:e.url+"#post-comment",date:e.time||e.insertedAt}));btf.saveToLocal.set("waline-newest-comments",JSON.stringify(e),10/1440),a(e)}catch(e){console.error(e),document.querySelector("#card-newest-comments .aside-list").textContent="无法获取评论，请确认相关配置是否正确"}})())};e(),btf.addGlobalFn("pjaxComplete",e,"waline_newestComment")})</script><script defer src="/js/custom.js"></script><script src="https://jsd.cdn.zzko.cn/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors=["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"];var pjax=new Pjax({elements:'a:not([target="_blank"])',selectors:pjaxSelectors,cacheBust:!1,analytics:!1,scrollRestoration:!1});const triggerPjaxFn=e=>{e&&Object.values(e).forEach(e=>{e()})};document.addEventListener("pjax:send",function(){btf.removeGlobalFnEvent("pjax"),btf.removeGlobalFnEvent("themeChange");var e=document.body.classList;e.contains("read-mode")&&e.remove("read-mode"),triggerPjaxFn(window.globalFn.pjaxSend)}),document.addEventListener("pjax:complete",()=>{document.querySelectorAll("script[data-pjax]").forEach(e=>{const t=document.createElement("script");var a=e.text||e.textContent||e.innerHTML||"";Array.from(e.attributes).forEach(e=>t.setAttribute(e.name,e.value)),t.appendChild(document.createTextNode(a)),e.parentNode.replaceChild(t,e)}),triggerPjaxFn(window.globalFn.pjaxComplete)}),document.addEventListener("pjax:error",e=>{404===e.request.status&&pjax.loadUrl("/404")})</script><script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div class="docsearch-wrap"><div id="docsearch" style="display:none"></div><link rel="stylesheet" href="https://jsd.cdn.zzko.cn/npm/@docsearch/css/dist/style.css"><script src="https://jsd.cdn.zzko.cn/npm/@docsearch/js/dist/umd/index.js"></script><script>(()=>{docsearch(Object.assign({appId:"97MUPN4DMC",apiKey:"a003a39f337f5186ec11f5f92bae62b3",indexName:"ccknbc",container:"#docsearch"},{placeholder:"Ctrl/⌘ + K 唤醒搜索服务",maxResultsPerGroup:7,translations:{button:{buttonText:"搜索",buttonAriaLabel:"搜索"},modal:{searchBox:{resetButtonTitle:"清空",resetButtonAriaLabel:"清空",cancelButtonText:"取消",cancelButtonAriaLabel:"取消"},startScreen:{recentSearchesTitle:"最近搜索历史",noRecentSearchesText:"搜索历史为空",saveRecentSearchButtonTitle:"保存搜索记录",removeRecentSearchButtonTitle:"清除搜索记录",favoriteSearchesTitle:"收藏夹",removeFavoriteSearchButtonTitle:"移出收藏夹"},errorScreen:{titleText:"未能获取搜索结果",helpText:"您可能需要检查您的网络连接"},footer:{selectText:"选择",selectKeyAriaLabel:"回车键",navigateText:"切换",navigateUpKeyAriaLabel:"方向键上",navigateDownKeyAriaLabel:"方向键下",closeText:"关闭",closeKeyAriaLabel:"退出键",searchByText:"搜索服务提供: DocSearch by"},noResultsScreen:{noResultsText:"未搜索到相关内容",suggestedQueryText:"您可尝试搜索",reportMissingResultsText:"确认搜索结果是正确的？",reportMissingResultsLinkText:"反馈给Algolia"}}}}));const e=()=>{document.querySelector(".DocSearch-Button").click()};var t=()=>{btf.addEventListenerPjax(document.querySelector("#search-button > .search"),"click",e)};t(),window.addEventListener("pjax:complete",t)})()</script></div></div><script>const copyright_enable=!0</script><script src="https://jsd.cdn.zzko.cn/npm/turndown/dist/turndown.min.js"></script><script src="https://jsd.cdn.zzko.cn/gh/ccknbc-forked/hexo-butterfly-copymarkdown/lib/copyMarkdown.min.js"></script><script src="https://jsd.cdn.zzko.cn/gh/ccknbc-forked/hexo-butterfly-copymarkdown/lib/reprint.min.js"></script><script>(function (w, d, s, id) {
        if (typeof (w.webpushr) !== 'undefined') return;
        w.webpushr = w.webpushr || function () { (w.webpushr.q = w.webpushr.q || []).push(arguments) };
        var js, fjs = d.getElementsByTagName(s)[0];
        js = d.createElement(s);
        js.id = id;
        js.async = 1;
        js.src = "https://cdn.webpushr.com/app.min.js";
        fjs.parentNode.appendChild(js);
        }(window, document, 'script', 'webpushr-jssdk'));

        webpushr('setup', {
        'key': 'BB9Y-w9p3u0CKA7UP9nupB6I-_NqE2MuODmKJjyC4W2YflX06Ff_hEhrNJfonrut5l6gCa28gC83q2OII7Qv-oA',
        'sw': 'none'
        });
        </script></body></html>